package patterns.design.e3t6;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;

import javax.xml.ws.soap.AddressingFeature.Responses;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;


public class Downloader implements ResourcesProvider {
	private CloseableHttpClient httpClient;
	
	public Downloader(){
		httpClient = HttpClients.createDefault();
	}
	
	@Override
	public Resource provideResource(String url) throws Exception{
		
		System.out.println("File will be downloaded.");
		
		Resource result = null;
		CloseableHttpResponse response = null;
		HttpEntity entity;
		InputStream contentInStream = null;
		HttpGet getResource = new HttpGet(url);
		try 
		{
			response = httpClient.execute(getResource);
		}
		catch (Exception e)
		{
			System.err.println("Error while executing request.");
			e.printStackTrace();
		}
		finally
		{
			int statusCode = response.getStatusLine().getStatusCode();
			if((statusCode < 200) || (statusCode >= 300)) {
				throw new Exception("Invalid response status: " + response.getStatusLine().getReasonPhrase());
			}
		}
		
		try
		{
			System.out.println("Caching dowloaded file.");
			
			entity = response.getEntity();
			contentInStream = entity.getContent();
			byte[] buffer = new byte[8192];
			URL urlObject = new URL(url);
			File contentFile = new File(urlObject.getPath().replace('/','_'));
			FileOutputStream foStream = new FileOutputStream(contentFile);
			int lenght;
			while((lenght = contentInStream.read(buffer)) > 0)
			{
				foStream.write(buffer, 0, lenght);
			}
			foStream.close();
			result = new Resource(contentFile, url);
		}
		catch (Exception e)
		{
			System.err.println("Error while dealing with response content.");
			e.printStackTrace();
		}
		return result;
	}

}
